package org.ecpkn.PAGridSim.core.tasksCreation;

import java.util.Random;

import org.ecpkn.PAGridSim.core.configuration.Configuration;

public class ExponentialDistributionTaskCreator extends PeriodTaskCreator {
	private static final class Const {

		private static final long SEED = 7L * 5 * 82 * 03 * 98;
		//private static final long SEED = 4L * 65 * 32 * 73 * 18 + 03;

		// task's length is measured by time:a CPU of standard rating takes that
		// quantity of time to execute a job of this task
		private static final double LAMDA = 0.0262;
		private static final double LELEND_PARAM = -1.25;

	}

	private static Random random = new Random(Const.SEED);
	private double LastArrivingTime = 0;

	@Override
	protected double defineTaskPeriod(int taskNumber) {
		// random double value is between 0-1
		return Configuration.getInstance().toDecimalFormatDouble(
				taskLength.get(taskNumber) * (1 + random.nextDouble() * 5));
	}

	@Override
	protected double defineTaskLength(int taskNumber) {
		// random double value is between 0-1
		double r = random.nextDouble();
		double length = Math.pow(r, 1 / Const.LELEND_PARAM);

		taskLength.add(taskNumber, length);
		return length;
	}

	@Override
	protected double defineTaskArrivingTime(int taskNumber) throws Exception {
		double newArrive = -(1 / Const.LAMDA) * Math.log(random.nextDouble());
		double arrivingTime = LastArrivingTime + newArrive;
		LastArrivingTime = arrivingTime;
		return arrivingTime / EXPERIMENTLENGTH;
	}

	@Override
	protected int defineTaskRepeatNumber(int taskNumber) {
		double r=random.nextDouble();
		int n=(int) Math.ceil(Math.pow((1/r),(1/1.05)))+50;
		return n;
	}

	@Override
	protected int defineTaskSetSize() {

		return Configuration.getInstance().getParameterInt(
				Configuration.Const.SIMULATION_TASKNUMBER);
	}

	@Override
	protected double reDefinePeriod(int TaskNumber) {
		double period = defineTaskPeriod(TaskNumber);
		if (period < MINPERIOD) {
			period = MINPERIOD;
		}
		return period;
	}
}
